<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>块级作用域</title>
</head>
<body>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
</body>

<script>
  // ES5中的var是没有块级作用域(if/for)
  // ES6中的let是有块级作用域的(if/for)

  var buttons = document.getElementsByTagName('button');

  // ES5的for和if中没有var的块级作用域,需要闭包操作
  // 为什么闭包可以解决问题:因为函数是一个作用域
  /*for (var i = 0; i < buttons.length; i++) {
    (function (i) {
      buttons[i].addEventListener('click', function () {
        console.log('第' + i + '个按钮');
      })
    })(i)
  }*/

  // ES6的let有块级作用域,所以可以直接操作
  for (let i = 0; i < buttons.length; i++) {
      buttons[i].addEventListener('click', function () {
        console.log('第' + i + '个按钮');
      })
  }


  // 为什么闭包可以解决问题:因为函数是一个作用域
  // 闭包是个什么原理: 首先看闭包的写法"(function(i){...})(i)",可以这样看,把(function(i){...})看成一个没有函数名的函数,
  // 然后,后边的(i)看做是在调用这个没有函数名的函数并传入参数i,那么闭包中的这个函数就会获得这个参数值进行业务处理,因为函数是有
  // 作用域的,所以后边循环对i改变的参数不会影响到当前i中的值,进而解决了ES5中for中没有作用域产生的问题

</script>
</html>
